# -*- coding: utf-8 -*-
# @Author: Tim Liu
# @Date: 2024-10-17
# @Last Modified by: Tim Liu
# @Last Modified time: 2025-1-3

# @Description: api endpoints for conversation crud

from fastapi import APIRouter, Depends, Security
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload

from utils.response import SuccessResponse

from apps.vadmin.auth.utils.current import OpenAuth, AllUserAuth
from apps.vadmin.auth.utils.validation.auth import Auth
from crewplus.helper.verify import get_api_key
from crewplus.apps.apikey.models.account_api_key import AccountApiKey
from crewplus.services.conversation.mongodb_conversation_service import MongoDBConversationService

from core.database import db_getter
from core.dependencies import IdList
from core.exception import CustomException

from utils import status
from . import schemas, cruds, params, models
from datetime import datetime

app = APIRouter()

###########################################################
#    Conversation Endpoints
###########################################################
@app.get("/conversations", summary="Get Conversation list")
async def get_conversations(p: params.ConversationParams = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter) ):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    model = models.ConversationDB
    options = [joinedload(model.create_user)]
    schema = schemas.ConversationListOut
    datas, count = await cruds.ConversationDal(db).get_datas(
        **p.dict(),
        v_options=options,
        v_schema=schema,
        v_return_count=True
    )
    return SuccessResponse(datas, count=count)

@app.post("/conversation/start", summary="Start a conversation")
async def start_conversation(data: schemas.Conversation, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter) ):
    """STart a conversation"""
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    create_user_id = data.create_user_id
    if not data.create_user_id:
        create_user_id = apikey.user_id
    
    convSrv = MongoDBConversationService()  # Use MongoDBConversationService
    data = convSrv.new_conversation(user_id=create_user_id)
    
    return SuccessResponse(await cruds.ConversationDal(db).create_data(data=data))

@app.put("/conversation/end", summary="End a conversation")
async def end_conversation(data: schemas.Conversation, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter) ):
    """End a conversation"""
   
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    

    # find conversation with session_id and update end time
    #schema = schemas.Conversation
    
    converse = await cruds.ConversationDal(db).get_data(session_id=data.session_id)
    
    data_id = converse.id

    converse.converse_end_time = str(datetime.now())
    converse.update_datetime = str(datetime.now())
    
    if not converse.create_user_id:
        converse.create_user_id = apikey.user_id
    
    return SuccessResponse(await cruds.ConversationDal(db).put_data(data_id, converse))

@app.get("/conversation/{data_id}", summary="Get a conversation by id")
async def get_conversation(data_id: int, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter) ):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)   
        
    schema = schemas.ConversationSimpleOut
    return SuccessResponse(await cruds.ConversationDal(db).get_data(data_id, v_schema=schema))

@app.delete("/conversations", summary="batch delete conversations", description="batch hard delete conversations from db")
async def delete_conversations(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
    #TODO: check permission, account can only delete owned conversations within the same account
    
    await cruds.ConversationDal(auth.db).delete_datas(ids=ids.ids, v_soft=False)
    return SuccessResponse("Successfully deleted")
